/*
 * @Author: hongbin
 * @Date: 2021-12-06 18:35:26
 * @LastEditors: hongbin
 * @LastEditTime: 2021-12-07 09:21:01
 * @Description:canvas 常用函数
 */

/**
 * @description: 垂直水平网格线
 * @param {CanvasRenderingContext2D} ctx canvasContext
 * @param {number} w 宽度
 * @param {number} h 高度
 * @param {number} wSpace x轴间距
 * @param {number} ySpace y轴间距
 * @return {void}
 */
export function gridLine(
  ctx: CanvasRenderingContext2D,
  w: number,
  h: number,
  wSpace = 100,
  ySpace = 100
) {
  for (let i = 0; i < w; i += wSpace) {
    ctx.beginPath();
    ctx.moveTo(i, 0);
    ctx.lineTo(i, h);
    ctx.strokeStyle = "#ddd";
    ctx.stroke();
    ctx.closePath();
  }

  for (let i = 0; i < h; i += ySpace) {
    ctx.beginPath();
    ctx.moveTo(0, i);
    ctx.lineTo(w, i);
    ctx.strokeStyle = "#ddd";
    ctx.stroke();
    ctx.closePath();
  }
}

/**
 * @description: 科技风线条
 * @param {CanvasRenderingContext2D} ctx canvasContext
 * @param {number} h 高度
 * @param {number} w 宽度
 * @param {number} space 间距
 * @param {string} lineColor 线条颜色
 * @return {void}
 */
export function technologyLine(
  ctx: CanvasRenderingContext2D,
  h: number,
  w: number,
  space: number,
  lineColor = "#ccc"
) {
  if (w < 765) return;
  for (let i = 0; i < h; i += space) {
    ctx.beginPath();
    ctx.strokeStyle = lineColor;
    ctx.moveTo(0, i);
    ctx.lineTo(i, h);
    ctx.moveTo(w, i);
    ctx.lineTo(w - i, h);
    ctx.stroke();
    ctx.closePath();
  }
}

const accuracy = 100; //渲染精度

const builtInLinearGradient = [
  ["#D8DC71", "#65D3CA"],
  ["#DF5675", "#4762ED"],
  ["#5BC9F4", "#A8F8A8"],
  ["#C64A69", "#D1AA5F"],
  ["#988EBF", "#4B3997"],
  ["#C79FAE", "#DE4477"],
  ["#CFAA9E", "#CD7232"],
  ["#96AE92", "#354F73"],
  ["#313573", "#6F7AA5"],
  ["#E7BDAA", "#524C8A"],
  ["#9F44B7", "#BA8BA2"],
  ["#C4446A", "#C5A15A"],
];

/**
 * @description: 心形
 * @param {*} x x轴
 * @param {*} y y轴
 * @param {*} r 半径
 * @param {*} speed 速度
 * @return {Heart} new Heart
 */

const { random, floor, PI, pow, cos, sin } = Math;

export function Heart(
  ctx: CanvasRenderingContext2D,
  x: number,
  y: number,
  r: number,
  speed = 3
) {
  // @ts-ignore
  const self = this as any;
  self.r = r;
  self.x = x;
  self.y = y;
  self.speed = speed;
  self.ctx = ctx;

  const linearGradient = ctx.createLinearGradient(0, r * -10, r * 20, r * 20);
  const color =
    builtInLinearGradient[floor(random() * builtInLinearGradient.length)];
  const opacity = Math.round(Math.random() * 0xff)
    .toString(16)
    .padEnd(2, "5");
  linearGradient.addColorStop(0, `${color[0]}${opacity}`);
  linearGradient.addColorStop(1, `${color[1]}${opacity}`);
  // TODO 提供一些好看的渐变配色
  self.fillStyle = linearGradient;
  const point = [];
  for (let i = 0; i < accuracy; i++) {
    const step = (i / accuracy) * (PI * 2);
    const xx = r * (16 * pow(sin(step), 3));
    const yy =
      r *
      (13 * cos(step) - 5 * cos(2 * step) - 2 * cos(3 * step) - cos(4 * step));
    point.push(xx, yy);
  }
  self.point = point;
  self.draw();
}

/**
 * @description: 根据参数 绘制Heart
 */
Heart.prototype.draw = function () {
  const ctx = this.ctx;
  ctx.save(); //保存 rotate translate 状态
  ctx.beginPath();
  ctx.translate(this.x, this.y);
  ctx.rotate(PI);
  const point = this.point;

  for (let i = 0; i < point.length; i += 2) {
    ctx.lineTo(point[i], point[i + 1]);
  }

  ctx.fillStyle = this.fillStyle;
  ctx.strokeStyle = this.fillStyle;
  ctx.fill();
  ctx.stroke();
  ctx.closePath();
  ctx.restore(); // 释放状态
};

/**
 * @description:  向上移动
 */
Heart.prototype.moveUp = function () {
  this.y -= this.speed;
  this.draw();
};
